﻿using System;
using System.Collections.Generic;
using System.Data.Objects;
using System.Linq;
using Sissonix.ExtRest.RestSchemaModel.Model;
using Sissonix.Infrastructure;
using Sissonix.ExtRest.RestSchemaModel.Repository;


namespace Sissonix.ExtRest.RestSchemaModel.Repository
{
    public class EFApplicationRepository : EFRepositoryBase<Application>, IApplicationRepository
    {
        public EFApplicationRepository(UnitOfWork uow) : base(uow) { }
        public EFApplicationRepository() : base() { }
        public EFApplicationRepository(UnitOfWork uow, string ConnectionString): base(uow) {EFConnectionString = ConnectionString;}
        public EFApplicationRepository(string ConnectionString) : base() { EFConnectionString = ConnectionString; }

        public Application FindBy(object key, bool returnDeep)
        {
            long lKey = Int64.Parse(key.ToString());
            RestSchemaEntities ent = GetEFContext();
            //ObjectQuery<Application> Application = GetEFContext().Application;


            ObjectQuery<Application> qry = ent.Application;
            qry = (ObjectQuery<Application>)qry.Where("it.ApplicationID=" + lKey.ToString());
            if (returnDeep)
                qry = (ObjectQuery<Application>)qry.Include("Domains");

            Application rslt = null;
            try { rslt = qry.First(); } catch {}
            return rslt;
        }

        public Domain FindDomainBy(object key, bool returnDeep)
        {
            long lKey = Int64.Parse(key.ToString());
            RestSchemaEntities ent = GetEFContext();
            //ObjectQuery<Application> Application = GetEFContext().Application;


            ObjectQuery<Domain> qry = ent.Domain;
            qry = (ObjectQuery<Domain>)qry.Where("it.DomainID=" + lKey.ToString());
            if (returnDeep)
                qry = (ObjectQuery<Domain>)qry.Include("Children");

            return qry.First();
        }

        #region IRepository<Application> Members
        public override Application FindBy(object key)
        {
            return FindBy(key, false);
        }
        public override IList<Application> FindAll()
        {
            return FindAll(0, 0, null, null);
        }

        public override int Count()
        {
            RestSchemaEntities ent = GetEFContext();
            var applications = ent.Application;
            return applications.Count();
        }

        public override IList<Application> FindAll(int? start, int? limit, string sortField, string sortDirection)
        {
            if (sortField == "") sortField = "ApplicationID";
            if (!start.HasValue) start = 0;
            if (!limit.HasValue) limit = int.MaxValue;

            RestSchemaEntities ent = GetEFContext();
            ObjectQuery<Application> applications = ent.Application;

            if (sortField != "")
                applications = applications.OrderBy("it." + sortField + " " + sortDirection);

            if (start.HasValue && limit.HasValue)
            {
                applications = (ObjectQuery<Application>)applications.Skip(start.Value);
                applications = (ObjectQuery<Application>)applications.Take(limit.Value);
            }

            return applications.Execute(MergeOption.AppendOnly).ToList<Application>();
        }
        #endregion

        #region RepositoryBase abstract Members
        protected override void EFPersistNewItem(Application item)
        {
            persistenceContext.AddObject("Application", item);
        }
        protected override void EFPersistUpdatedItem(Application item)
        {
            //This is very discouraging. In EF, you have to load the record
            //from the database first in order to update it.  What a waste!
            try
            {
                persistenceContext.Connection.Open();
                var rec = (from u in persistenceContext.Application where u.ApplicationID == item.ApplicationID select u)
                    .FirstOrDefault();
                if (rec != null)
                {
                    persistenceContext.ApplyPropertyChanges("Application", item);
                }
            }
            catch (Exception e)
            {
            }
            return; 
        }
        protected override void EFPersistDeletedItem(Application item)
        {
            persistenceContext.DeleteObject(item);
        }
        #endregion
    }
}
